#include <QVBoxLayout>
#include <QCompleter>
#include <QDirModel>
#include <QLineEdit>
#include <QTreeView>
#include <QComboBox>
#include <QMetaObject>
#include <QShortcut>
#include <QHeaderView>
#include <QDebug>

#include "QyFileSystemBrowser.h"

QyFileSystemBrowser::QyFileSystemBrowser( QWidget * parent ) : QWidget(parent) {

	QVBoxLayout * layout = new QVBoxLayout(this);
	QCompleter * pathCompleter = new QCompleter(this);
	dirModel = new QDirModel(this);
	pathEdit = new QLineEdit(this);
    treeView = new QTreeView(this);
	filterEditBox = new QComboBox(this);
	new QShortcut( QKeySequence("Alt+Up"), this, SLOT( cdUp() ), 0, Qt::WidgetWithChildrenShortcut );
	new QShortcut( QKeySequence("Backspace"), this, SLOT( cdUp() ), 0, Qt::WidgetWithChildrenShortcut );
	new QShortcut( QKeySequence("Return"), this, SLOT( returnPressed() ), 0, Qt::WidgetWithChildrenShortcut );
	new QShortcut( QKeySequence("Ctrl+Up"), this, SLOT( setPathEditFocus() ), 0, Qt::WidgetWithChildrenShortcut );
	new QShortcut( QKeySequence("Ctrl+Down"), this, SLOT( setFilterEditFocus() ), 0, Qt::WidgetWithChildrenShortcut );

	layout->addWidget(pathEdit);
	layout->addWidget(treeView);
	layout->addWidget(filterEditBox);
    treeView->setModel(dirModel);
	treeView->setObjectName("treeView");
    treeView->setSortingEnabled(true);
    treeView->sortByColumn( 0, Qt::AscendingOrder );
    treeView->setItemsExpandable(true);
    treeView->setAllColumnsShowFocus(true);
    treeView->header()->setResizeMode( 0, QHeaderView::ResizeToContents );
	treeView->setFocus();
	pathCompleter->setModel( new QDirModel( QStringList() << "*", QDir::AllDirs|QDir::NoDotAndDotDot, QDir::Name, pathCompleter ) );
	pathEdit->setCompleter(pathCompleter);
	pathEdit->setObjectName("pathEdit");
	filterEditBox->setObjectName("filterEditBox");
	filterEditBox->setEditable(true);
	filterEditBox->setEditText("*");
	setPath( QDir::homePath() );
	setFocusProxy(treeView);

	setDefaultNameFilters( QStringList() << "*.cpp;*.h;*.pro" );

	QMetaObject::connectSlotsByName(this);

}

QString QyFileSystemBrowser::currentPath() const {

	return dirModel->filePath( treeView->rootIndex() );
}

QString QyFileSystemBrowser::currentFileName() const {

	return dirModel->fileName( treeView->currentIndex() );
}

QString QyFileSystemBrowser::currentFilePath() const {

	return dirModel->filePath( treeView->currentIndex() );
}

QFileInfo QyFileSystemBrowser::currentFileInfo() const {

	return dirModel->fileInfo( treeView->currentIndex() );
}

void QyFileSystemBrowser::setPath( const QString & path ) {

	QDir dir(path);

	if ( !dir.exists() )
		return;

	treeView->setRootIndex( dirModel->index( dir.absolutePath() ) );
	pathEdit->blockSignals(true);
	pathEdit->setText( dir.absolutePath() );
	pathEdit->blockSignals(false);

	treeView->collapseAll();
	treeView->setCurrentIndex( treeView->rootIndex().child( 0, 0 ) );

}

void QyFileSystemBrowser::cdUp() {

	QModelIndex modelIndex = dirModel->index( pathEdit->text() );

	if ( modelIndex.isValid() ) {

		modelIndex = modelIndex.parent();
		setPath( dirModel->filePath(modelIndex) );

	}

}

void QyFileSystemBrowser::setDefaultNameFilters( QStringList nameFilters ) {

	p_defaultNamefilters = nameFilters;
	QString text( filterEditBox->currentText() );
	filterEditBox->clear();

	foreach ( QString nameFilter, p_defaultNamefilters )
		filterEditBox->addItem(nameFilter);

	filterEditBox->setEditText(text);

}

void QyFileSystemBrowser::on_treeView_doubleClicked( const QModelIndex & modelIndex ) {

	QFileInfo info( dirModel->fileInfo(modelIndex) );

// 	if ( info.isDir() )
// 		setPath( info.filePath() );

	emit activated( info.filePath() );

}

void QyFileSystemBrowser::on_pathEdit_textChanged( const QString & path ) {

	if ( path.contains("/..") || path.contains("/./") )
		return setPath(path);

	QModelIndex modelIndex = dirModel->index(path);

	if ( modelIndex.isValid() )
		treeView->setRootIndex(modelIndex);

}

void QyFileSystemBrowser::on_filterEditBox_editTextChanged( const QString & text ) {
	QString cachePath( currentPath() );
	dirModel->setFilter(QDir::AllDirs|QDir::NoDotAndDotDot|QDir::Files);
	dirModel->setNameFilters( text.split(";") );
	setPath(cachePath);

}

void QyFileSystemBrowser::returnPressed() {

	on_treeView_doubleClicked( treeView->currentIndex() );

}

void QyFileSystemBrowser::setPathEditFocus() {

	pathEdit->setFocus();

}

void QyFileSystemBrowser::setFilterEditFocus() {

	filterEditBox->setFocus();

}
